Hamming (7,4) coding
A colleague of mine asked me about a simple demonstration of Hamming code. It is inspired by this link, but unfortunately the code is not available anymore. Below is what I did.
Two utilitary functions
For encoding and decoding to and from binary number representations
In [2]:
from random import randint
import numpy as np
# We begin with two utilitary functions
def dec2binmat(n):
#This converts a decimal number into a matrix of (int) bits
ll=list("{0:04b}".format(n)) #.format give a string which is converted to a list
ll=[int(k) for k in ll] # for each element in the list convert to int
return np.matrix(ll) # return a matrix
def binmat2dec(m):
#This converts a matrix of (int) bits into a decimal number
m=m.reshape(1,size(m),order='C').tolist()[0] # convert to list
s=0
l=len(m)-1
for k,v in enumerate(m):
s+=m[k]*2**(l-k)
return s
# examples
n=5
m=dec2binmat(n)
print("Number {} converted into binary: {}".format(n,m))
nn=binmat2dec(m)
print("And back to a decimal number: {}".format(nn))
Hamming(7,4) Codec
In [27]:
#Method to encode message
def encode(message):
# message: binary string representation of the (int) number
message = np.matrix(message)
#print(message)
#Hamming (7,4) generating matrix to encode the message
g = np.matrix([[1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 0, 1, 0, 1],
[0, 0, 1, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 1]])
#Multiply the message with the matrix to encode the message with module 2
return ( message * g ) % 2
#Method to decode message
def decode(message):
#Matrix to decode the message
h = np.matrix([[0, 0, 0, 1, 1, 1, 1],
[0, 1, 1, 0, 0, 1, 1],
[1, 0, 1, 0, 1, 0, 1]])
#Multiply the message with the matrix to verify the message with module 2
#This is the syndrom
hy = ( h * message.T) % 2 #%2 is the modulo 2 operation
#Get the integer value of the binary as result of the previous operation
#print(hy)
s=binmat2dec(hy)
print("Syndrom: ",s)
#print(s)
# the syndrom gives the bit number.
#Since indexes begin at 0 there is a shift of one
if s!=0:
message[0,s-1]=(message[0,s-1]+1) %2
return (s,message)
A test
And finally a test of encoding-decoding with some corruptions of the message.
In [28]:
def hamm_tst():
n=int(input('Please input a number in [0,15] '))
if n<0 or n>15:
print("n must be between 0 and 15")
raise ValueError
print('binary number: ', bin(n) )
b=dec2binmat(n)
enc=encode(b)
print('encoded version: ', enc)
print('decoded version: ', decode(enc))
print('.'*20)
print('let us add a random error: ')
noise=random.randint(0,7) # change one bit among 7 possible
newenc=enc.copy()
newenc[0,noise]=(newenc[0,noise]+1) %2
nb=noise+1
print('bit number %d is changed: ' % nb)
print("new message ",newenc)
print('decoded version: ', decode(newenc)[1])
print('The End')
hamm_tst()
An object-oriented version
Let us now design an object 'Hamming codec'.
In [29]:
class Hamming_codec():
def __init__(self):
self.indata=[[0,0,0,0]]
def data(self,indata=None):
if indata:
indata=list(indata)
ll=[int(k) for k in indata] # for each element in the list convert to int
self.indata=np.matrix(ll)
else:
self.decode()
def code(self,incode=None):
self.code=encode(self.indata)
print("Code: ",self.code)
def decode(self,incode=None):
if incode:
indata=list(incode)
ll=[int(k) for k in indata] # for each element in the list convert to int
self.code=np.matrix(ll)
r=decode(self.code)[1]
print("Decoded value: ",r)
In [30]:
t=Hamming_codec()
t.data('1101')
t.code()
t.decode()
print("\nAnd now introduce an error...")
t.decode('1101011')
In [33]:
HTML(the_end(theNotebook))
Out[33]: